{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div style=\"color:#777777;background-color:#ffffff;font-size:12px;text-align:right;\">\n",
    "\tprepared by Abuzer Yakaryilmaz (QuSoft@Riga) | November 02, 2018\n",
    "</div>\n",
    "<table><tr><td><i> I have some macros here. If there is a problem with displaying mathematical formulas, please run me to load these macros.</i></td></td></table>\n",
    "$ \\newcommand{\\bra}[1]{\\langle #1|} $\n",
    "$ \\newcommand{\\ket}[1]{|#1\\rangle} $\n",
    "$ \\newcommand{\\braket}[2]{\\langle #1|#2\\rangle} $\n",
    "$ \\newcommand{\\inner}[2]{\\langle #1,#2\\rangle} $\n",
    "$ \\newcommand{\\biginner}[2]{\\left\\langle #1,#2\\right\\rangle} $\n",
    "$ \\newcommand{\\mymatrix}[2]{\\left( \\begin{array}{#1} #2\\end{array} \\right)} $\n",
    "$ \\newcommand{\\myvector}[1]{\\mymatrix{c}{#1}} $\n",
    "$ \\newcommand{\\myrvector}[1]{\\mymatrix{r}{#1}} $\n",
    "$ \\newcommand{\\mypar}[1]{\\left( #1 \\right)} $\n",
    "$ \\newcommand{\\mybigpar}[1]{ \\Big( #1 \\Big)} $\n",
    "$ \\newcommand{\\sqrttwo}{\\frac{1}{\\sqrt{2}}} $\n",
    "$ \\newcommand{\\dsqrttwo}{\\dfrac{1}{\\sqrt{2}}} $\n",
    "$ \\newcommand{\\onehalf}{\\frac{1}{2}} $\n",
    "$ \\newcommand{\\donehalf}{\\dfrac{1}{2}} $\n",
    "$ \\newcommand{\\hadamard}{ \\mymatrix{rr}{ \\sqrttwo & \\sqrttwo \\\\ \\sqrttwo & -\\sqrttwo }} $\n",
    "$ \\newcommand{\\vzero}{\\myvector{1\\\\0}} $\n",
    "$ \\newcommand{\\vone}{\\myvector{0\\\\1}} $\n",
    "$ \\newcommand{\\vhadamardzero}{\\myvector{ \\sqrttwo \\\\  \\sqrttwo } } $\n",
    "$ \\newcommand{\\vhadamardone}{ \\myrvector{ \\sqrttwo \\\\ -\\sqrttwo } } $\n",
    "$ \\newcommand{\\myarray}[2]{ \\begin{array}{#1}#2\\end{array}} $\n",
    "$ \\newcommand{\\X}{ \\mymatrix{cc}{0 & 1 \\\\ 1 & 0}  } $\n",
    "$ \\newcommand{\\Z}{ \\mymatrix{rr}{1 & 0 \\\\ 0 & -1}  } $\n",
    "$ \\newcommand{\\Htwo}{ \\mymatrix{rrrr}{ \\frac{1}{2} & \\frac{1}{2} & \\frac{1}{2} & \\frac{1}{2} \\\\ \\frac{1}{2} & -\\frac{1}{2} & \\frac{1}{2} & -\\frac{1}{2} \\\\ \\frac{1}{2} & \\frac{1}{2} & -\\frac{1}{2} & -\\frac{1}{2} \\\\ \\frac{1}{2} & -\\frac{1}{2} & -\\frac{1}{2} & \\frac{1}{2} } } $\n",
    "$ \\newcommand{\\CNOT}{ \\mymatrix{cccc}{1 & 0 & 0 & 0 \\\\ 0 & 1 & 0 & 0 \\\\ 0 & 0 & 0 & 1 \\\\ 0 & 0 & 1 & 0} } $\n",
    "$ \\newcommand{\\norm}[1]{ \\left\\lVert #1 \\right\\rVert } $"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<h2> Matrices: Tensor Product</h2>\n",
    "\n",
    "Tensor product is defined between any two matrices. The result is a new big matrix.\n",
    "\n",
    "Its formal definition is technical. Therefore, we use examples to descibe it. \n",
    "\n",
    "Let's start with a simple case.\n",
    "\n",
    "<i>A vector is also a matrix. Therefore, tensor product can also be defined between two vectors or between one vector and one matrix.</i>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<h3> Tensor product of two vectors </h3>\n",
    "\n",
    "We have two vectors: $ u = \\myrvector{-2\\\\3} $ and $ v = \\myrvector{1 \\\\ 2 \\\\ -3} $.\n",
    "\n",
    "The tensor product of $u$ and $ v $ is denoted $ u \\otimes v $.\n",
    "\n",
    "We can consider the tensor product as extending $ u $ by $ v $:\n",
    "\n",
    "$$\n",
    "    u \\otimes v =  \\myrvector{-2\\\\3} \\otimes \\myrvector{1 \\\\ 2 \\\\ -3} =\n",
    "   \\myrvector{ -2 \\cdot  \\myrvector{1 \\\\ 2 \\\\ -3} \\\\ 3 \\cdot  \\myrvector{1 \\\\ 2 \\\\ -3} } =\n",
    "   \\myrvector{ -2 \\\\ -4 \\\\ 6 \\\\ 3 \\\\ 6 \\\\ -9 }.\n",
    "$$\n",
    "\n",
    "Here, $ -2 $ in $ u $ is replaced with the vector $ (-2 \\cdot v) $, and $ 3 $ in $ u $ is replaced with the vector $ 3 v $.\n",
    "\n",
    "Thus each entry of $ u $ is replaced by a 3-dimensional vector, and the dimension of the result vector is $ 6~(=2 \\cdot 3) $.\n",
    "\n",
    "Algorithmically, each element in $ u $ is replaced by the multiplication of this element with the vector $ v $.\n",
    "\n",
    "Let's find $ v \\otimes u $ in python."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# vector v\n",
    "v = [1,2,3]\n",
    "# vector u\n",
    "u=[-2,3]\n",
    "\n",
    "vu = []\n",
    "\n",
    "for i in range(len(v)): # Each element of v will be replaced\n",
    "    for j in range(len(u)): # the vector u will come to the replaced place after multiplying with the entry there\n",
    "        vu.append( v[i] * u[j] )\n",
    "\n",
    "print(\"v=\",v)\n",
    "print(\"u=\",u)\n",
    "print(\"vu=\",vu)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<h3> Task 1 </h3>\n",
    "\n",
    "Find $ u \\otimes v $ and $ v \\otimes u $ for the given vectors $ u = \\myrvector{-2 \\\\ -1 \\\\ 0 \\\\ 1} $ and $ v = \\myrvector{ 1 \\\\ 2 \\\\ 3 } $."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#\n",
    "# your solution is here\n",
    "#\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<a href=\"..\\bronze-solutions\\B22_Python_Lists_Tensor_Product_Solutions.ipynb#task1\">click for our solution</a>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<b> Note:</b>\n",
    "\n",
    "Tensor products are useful, when we have a system composed by two (or more) sub-systems.\n",
    "\n",
    "We will see the basic applications and usage of tensor products."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<h3> Tensor product of two matrices </h3>\n",
    "\n",
    "The definition is the same.\n",
    "\n",
    "Let's find $ M \\otimes N $ and $ N \\otimes M $ for the given matrices\n",
    "$\n",
    "    M = \\mymatrix{rrr}{-1 & 0 & 1 \\\\ -2 & -1 & 2 \\\\ 1 & 2 & -2} ~~\\mbox{and}~~ \n",
    "    N = \\mymatrix{rrr}{0 & 2 & 1 \\\\ 3 & -1 & -2 \\\\ -1 & 1 & 0}.\n",
    "$\n",
    "\n",
    "$ M \\otimes N $: Each element of $ M $ will be replaced with the whole matrix $ N $ after multiplying with this element.\n",
    "\n",
    "$$\n",
    "    M \\otimes N =\n",
    "    \\mymatrix{rrr}{-1 & 0 & 1 \\\\ -2 & -1 & 2 \\\\ 1 & 2 & -2} \\otimes \\mymatrix{rrr}{0 & 2 & 1 \\\\ 3 & -1 & -2 \\\\ -1 & 1 & 0}\n",
    "    =\n",
    "    \\mymatrix{rrr}{ -1 \\mymatrix{rrr}{0 & 2 & 1 \\\\ 3 & -1 & -2 \\\\ -1 & 1 & 0} & 0 \\mymatrix{rrr}{0 & 2 & 1 \\\\ 3 & -1 & -2 \\\\ -1 & 1 & 0} & 1 \\mymatrix{rrr}{0 & 2 & 1 \\\\ 3 & -1 & -2 \\\\ -1 & 1 & 0} \\\\\n",
    "    -2 \\mymatrix{rrr}{0 & 2 & 1 \\\\ 3 & -1 & -2 \\\\ -1 & 1 & 0} & -1 \\mymatrix{rrr}{0 & 2 & 1 \\\\ 3 & -1 & -2 \\\\ -1 & 1 & 0} & 2 \\mymatrix{rrr}{0 & 2 & 1 \\\\ 3 & -1 & -2 \\\\ -1 & 1 & 0} \\\\\n",
    "    1 \\mymatrix{rrr}{0 & 2 & 1 \\\\ 3 & -1 & -2 \\\\ -1 & 1 & 0} & 2 \\mymatrix{rrr}{0 & 2 & 1 \\\\ 3 & -1 & -2 \\\\ -1 & 1 & 0} & -2 \\mymatrix{rrr}{0 & 2 & 1 \\\\ 3 & -1 & -2 \\\\ -1 & 1 & 0}}\n",
    "$$\n",
    "\n",
    "It is a boring task because of repetitions. \n",
    "\n",
    "Let us do this once by hand (in mind), and then check the result by python."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "$$\n",
    "    M \\otimes N = \\mymatrix{rrrrrrrrr}{\n",
    "        0 & -2 & -1 & 0 & 0 & 0 & 0 & 2 & 1 \\\\\n",
    "        -3 & 1 & 2 & 0 & 0 & 0 & 3 & -1 & -2 \\\\\n",
    "        1 & -1 & 0 & 0 & 0 & 0 & -1 & 1 & 0 \\\\\n",
    "        0 & -4 & -2 & 0 & -2 & -1 & 0 & 4 & 2 \\\\\n",
    "        -6 & 2 & 4 & -3 & 1 & 2 & 6 & -2 & -4 \\\\\n",
    "        2 & -2 & 0 & 1 & -1 & 0 & -2 & 2 & 0 \\\\\n",
    "        2 & 1 & 0 & 1 & -1 & 0 & -2 & 2 & 0 \\\\\n",
    "        0 & 2 & 1 & 0 & 4 & 2 & 0 &  -4 & -2 \\\\\n",
    "        3 & -1 & -2 & 6 & -2 & -4 & -6 & 2 & 4 \\\\\n",
    "        -1 & 1 & 0 & -2 & 2 & 0 & 2 & -2 & 0\n",
    "    }\n",
    "$$\n",
    "\n",
    "Now, let's find the same matrix in python.\n",
    "\n",
    "This time we will use a four nested for-loops."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# matrix M\n",
    "M = [ \n",
    "    [-1,0,1],\n",
    "    [-2,-1,2],\n",
    "    [1,2,-2]\n",
    "]\n",
    "\n",
    "# matrix N\n",
    "N = [\n",
    "    [0,2,1],\n",
    "    [3,-1,-2],\n",
    "    [-1,1,0]\n",
    "]\n",
    "\n",
    "# MN will be (9x9)-dimensional matrix\n",
    "# let's prepare it as a zero matrix\n",
    "# this helps us to easily fill it \n",
    "MN=[]\n",
    "for i in range(9):\n",
    "    MN.append([])\n",
    "    for j in range(9):\n",
    "        MN[i].append(0)\n",
    "\n",
    "for i in range(3): # row of M\n",
    "    for j in range(3): # column of M\n",
    "        for k in range(3): # row of N\n",
    "            for l in range(3): # column of N\n",
    "                MN[i*3+k][3*j+l] = M[i][j] * N[k][l] \n",
    "\n",
    "print(\"M-tensor-N is\")                \n",
    "for i in range(9):\n",
    "    print(MN[i])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's find $ N \\otimes M $ in python.\n",
    "\n",
    "We use the same code by interchanging $ N $ and $ M $."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# matrix M and N were defined above\n",
    "\n",
    "# matrix NM will be prepared as a (9x9)-dimensional zero matrix\n",
    "NM=[]\n",
    "for i in range(9):\n",
    "    NM.append([])\n",
    "    for j in range(9):\n",
    "        NM[i].append(0)\n",
    "\n",
    "for i in range(3): # row of N\n",
    "    for j in range(3): # column of N\n",
    "        for k in range(3): # row of M\n",
    "            for l in range(3): # column of M\n",
    "                NM[i*3+k][3*j+l] = N[i][j] * M[k][l] \n",
    "\n",
    "print(\"N-tensor-M is\")\n",
    "for i in range(9):\n",
    "    print(NM[i])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<h3> Task 2 </h3>\n",
    "\n",
    "Find $ A \\otimes B $ for the given matrices\n",
    "$\n",
    "    A = \\mymatrix{rrr}{-1 & 0 & 1 \\\\ -2 & -1 & 2} ~~\\mbox{and}~~ \n",
    "    B = \\mymatrix{rr}{0 & 2 \\\\ 3 & -1 \\\\ -1 & 1 }.\n",
    "$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#\n",
    "# your solution is here\n",
    "#\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<a href=\"..\\bronze-solutions\\B22_Python_Lists_Tensor_Product_Solutions.ipynb#task2\">click for our solution</a>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<h3> Task 3 </h3>\n",
    "\n",
    "Find $ B \\otimes A $ for the given matrices\n",
    "$\n",
    "    A = \\mymatrix{rrr}{-1 & 0 & 1 \\\\ -2 & -1 & 2} ~~\\mbox{and}~~ \n",
    "    B = \\mymatrix{rr}{0 & 2 \\\\ 3 & -1 \\\\ -1 & 1 }.\n",
    "$\n",
    "\n",
    "You can use the code in your (our) solution for Task 2.\n",
    "\n",
    "But please be careful with the indices and range values, and how they are interchanged (!)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#\n",
    "# your solution is here\n",
    "#\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<a href=\"..\\bronze-solutions\\B22_Python_Lists_Tensor_Product_Solutions.ipynb#task3\">click for our solution</a>"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
